package pl.wroc.uni.ii.evolution.servlets.databasesupport;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.sql.SQLException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import pl.wroc.uni.ii.evolution.servlets.databasesupport.providers.EvDatabaseProvider;
import pl.wroc.uni.ii.evolution.servlets.databasesupport.providers.EvDatabaseProviderFactory;

/**
 * This servlet is reponsible for:
 * <ul>
 * <li> uploading JAR files with tasks </li>
 * <li> uploading individuals </li>
 * </ul>
 * 
 * @author Marcin Golebiowski, Piotr Lipinski
 */
public class EvUploadServlet extends HttpServlet {

  private static final long serialVersionUID = 1090590698352987769L;
  private String database_url = null;
  private String database_user = null;
  private String database_password = null;
  private String provider = null;



  /** *************************************************************************** */

  public void init(ServletConfig config) throws ServletException {
    super.init(config);

    database_url = config.getInitParameter("DATABASE_URL");
    database_password = config.getInitParameter("DATABASE_PASSWORD");
    database_user = config.getInitParameter("DATABASE_USER");

    provider = config.getInitParameter("DATABASE_PROVIDER");
    
    
    System.out.println("USER: " + database_user );
    System.out.println("PASSWORD: " + database_password );
    
  }

  /***************************************************************************** */

  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    ObjectInputStream input = new ObjectInputStream(request.getInputStream());
    
    int command = input.readInt();
    switch (command) {
    case EvDBOperations.CMD_ADD_INDIVIDUAL:
      uploadIndividual(input, request, response);
      break;
    case EvDBOperations.CMD_ADD_SOLUTION_SPACES_FOR_TASK_AND_CELL:
      uploadSolutionSpace(input, request, response);
      break;
    case EvDBOperations.CMD_ADD_TASK:
      uploadTask(input, request, response);
      break;
    case EvDBOperations.CMD_SET_RESOURCE:
      setResource(input, request, response);
      break;

    case EvDBOperations.CMD_SAVE_STATISTICS:
      saveStatistic(input, request, response);
      break;
    }

    input.close();
  }

  private void saveStatistic(ObjectInputStream input, HttpServletRequest request, HttpServletResponse response) {
    try {
      long task_id = input.readLong();
      long cell_id = input.readLong();
      long node_id = input.readLong();
      int iteration = input.readInt();
      long time = input.readLong();
      Object stat = input.readObject();
   
      EvDatabaseProvider database = EvDatabaseProviderFactory.getProvider(provider);
      database.connect(database_url, database_user, database_password);
      database.saveStatistic(task_id, cell_id, node_id, stat, iteration, time);
      database.disconnect();
     
      response.setContentType("application/octet-stream");
      response.setHeader("content-disposition",
          "attachment; filename=\"setResource\"");
      ObjectOutputStream output = new ObjectOutputStream(response
          .getOutputStream());
      output.close();
      
    } catch (Exception ex) {
      ex.printStackTrace(System.out);
    }
    
  }

  private void setResource(ObjectInputStream input, HttpServletRequest request, HttpServletResponse response) {
  
  
    try {
      String name = (String) input.readObject();
      Object res =  input.readObject();
      
   
      EvDatabaseProvider database = EvDatabaseProviderFactory.getProvider(provider);
      database.connect(database_url, database_user, database_password);
      database.setResource(res, name);
      database.disconnect();
     
      response.setContentType("application/octet-stream");
      response.setHeader("content-disposition",
          "attachment; filename=\"setResource\"");
      ObjectOutputStream output = new ObjectOutputStream(response
          .getOutputStream());
      output.close();
      
    } catch (Exception ex) {
      ex.printStackTrace(System.out);
    }
  }

  private void uploadTask(ObjectInputStream input, HttpServletRequest request,
      HttpServletResponse response) throws IOException {
    try {
      String desc = (String) input.readObject();

      EvDatabaseProvider database = EvDatabaseProviderFactory.getProvider(provider);
      database.connect(database_url, database_user, database_password);
      int id = database.addTaskForSystem((byte[]) input.readObject(), desc);

      database.disconnect();

      response.setContentType("application/octet-stream");
      response.setHeader("content-disposition",
          "attachment; filename=\"evolution\"");
      ObjectOutputStream output = new ObjectOutputStream(response
          .getOutputStream());
      output.writeInt(id);
      output.close();

    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    } catch (SQLException ex) {

    } catch (InstantiationException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    }

  }

  private void uploadSolutionSpace(ObjectInputStream input,
      HttpServletRequest request, HttpServletResponse response)
      throws IOException {
    try {
      long task_id = input.readLong();
      long cell_id = input.readLong();
      Object space = input.readObject();

      EvDatabaseProvider database = EvDatabaseProviderFactory.getProvider(provider); 
      database.connect(database_url, database_user, database_password);
      int iteration = database.addSolutionSpace(task_id, cell_id, space);

      database.disconnect();

      response.setContentType("application/octet-stream");
      response.setHeader("content-disposition",
          "attachment; filename=\"evolution\"");
      ObjectOutputStream output = new ObjectOutputStream(response
          .getOutputStream());
      output.writeInt(iteration);
      output.close();

    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    } catch (SQLException ex) {

    } catch (InstantiationException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    }
  }

  private void uploadIndividual(ObjectInputStream input,
      HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    try {

      long instanceID = input.readLong();
      double objectiveValue = input.readDouble();
      Object individual = input.readObject();
      long creationCell = input.readLong();
      long creationNode = input.readLong();

      EvDatabaseProvider database = EvDatabaseProviderFactory.getProvider(provider);
      database.connect(database_url, database_user, database_password);

      int ID = database.addIndividual(individual, instanceID, objectiveValue,
          creationCell, creationNode);

      database.disconnect();

      response.setContentType("application/octet-stream");
      response.setHeader("content-disposition",
          "attachment; filename=\"evolution\"");
      ObjectOutputStream output = new ObjectOutputStream(response
          .getOutputStream());
      output.writeInt(ID);
      output.close();

    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    } catch (SQLException ex) {
      ex.printStackTrace();
    } catch (InstantiationException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    }
  }
  
  
}
